/**
 * Copyright (C) 2013 THALES NEDERLAND B.V. and/or its suppliers
 * 
 * THIS SOFTWARE SOURCE CODE AND ANY EXECUTABLE DERIVED THEREOF ARE PROPRIETARY
 * TO THALES NEDERLAND B.V. AND/OR ITS SUPPLIERS, AS APPLICABLE, AND SHALL NOT
 * BE USED IN ANY WAY OTHER THAN BEFOREHAND AGREED ON BY THALES NEDERLAND B.V.,
 * NOR BE REPRODUCED OR DISCLOSED TO THIRD PARTIES WITHOUT PRIOR WRITTEN
 * AUTHORIZATION BY THALES NEDERLAND B.V. AND/OR ITS SUPPLIERS, AS APPLICABLE.
 * 
 * $LastChangedDate: 2014-10-13 14:18:01 +0200 (ma, 13 okt 2014) $
 * $LastChangedRevision: 418 $
 * $LastChangedBy: atep $
 */

package com.thalesgroup.nl.trtdelft.dein.mapper;

import com.thalesgroup.nl.trtdelft.dein.mapper.api.AbstractMapperFunction;
import com.thalesgroup.nl.trtdelft.dein.mapper.api.MapperFunctionInputUpdatePolicy;
import com.thalesgroup.nl.trtdelft.dein.mapper.api.MapperFunctionInterface;
import com.thalesgroup.nl.trtdelft.dein.mapper.api.MapperFunctionOutputUpdatePolicy;
import com.thalesgroup.nl.trtdelft.dein.servlet.impl.Client;
import java.io.IOException;
import java.io.Serializable;
import java.net.URISyntaxException;
import org.apache.http.HttpException;
import org.apache.log4j.Logger;
import org.json.simple.JSONObject;

/**
 * Have the basic functionality to solve the various functions needed for a 
 * client-side web service
 * 
 * @author Thales Research and Technology Delft
 */
public abstract class AbstractMappedWebService extends AbstractMapperFunction implements MapperFunctionInterface {
    protected Logger log = Logger.getLogger(getClass());
	
    protected String external_server_url;
	
	/** Setup the connection to the remote server, and publish the local Servlet */
	@Override
        public void initialize() {
		super.initialize();
		setupClient();
	}
	
	protected void setupClient() {
		if(arguments.get("external_server_url") != null) { 
			external_server_url = arguments.get("external_server_url");
		}
	}

	protected String postMessage(String relativePath, JSONObject obj) {
		String returnValue = null;
		try {
			returnValue = 
				Client.post(external_server_url+(relativePath == null ? "" : relativePath), obj.toString());
		} catch (URISyntaxException ex) {
			log.error(null, ex);
		} catch (HttpException ex) {
			log.error(null, ex);
		} catch (IOException ex) {
			log.error(null, ex);
		}
		return returnValue;
	}
	
	/**
	 * Handle the receiving of Responses from Input capabilities 
	 * (i.e. the "input" variables)
	 */
	@Override
	public void input(String senderAddress, String inputVariableName, Serializable input) {
            System.out.println();

	}

	/**
	 * @return number of Input capabilities
	 */
	@Override 
	public int getNumberOfInputs() { 
		return inputs.getInputs().size(); 
	}
	
	/**
	 * Handle the receiving of a Request For Information 
	 * (i.e. the "queryReceive" variables)
	 */
	@Override
	public void setQueryVariable(String queryVariableName, Serializable value) {
		//Do Nothing special, just call super method
	     super.setQueryVariable(queryVariableName, value);
	}

	/**
	 * Handle the sending a Conclusion up the chain 
	 * (i.e. the "output" variables)
	 */
	@Override
	public Serializable getCurrentOutput(String string) throws IllegalStateException {
		//Do nothing
		return null;
	}

	/**
	 * Calculate the complete response message
	 */
	@Override
	public void computeOutput() throws IllegalStateException {
		// Do nothing
	}
	
	/**
	 * Calculate the response for a particular variable
	 */
	@Override
	public void computeOutput(String variableName) throws IllegalStateException {
            System.out.println();
		
	}
	
	/**
	 * @return is their a new output/conclusion available
	 */
	@Override 
	public boolean outputAvailable() { 
		return true; 
	}
	
	/**
	 * @return is this function/service able to respond with a conclusion/output
	 */
	@Override public boolean outputComputable() { 
		return true; 
	}
	
	@Override
	public MapperFunctionInputUpdatePolicy getInputUpdatePolicy() {
		return MapperFunctionInputUpdatePolicy.REPLACE;
	}
	
	@Override
	public MapperFunctionOutputUpdatePolicy getOutputUpdatePolicy() {
		return MapperFunctionOutputUpdatePolicy.ON_EACH_INPUT;
	}
	
	@Override 
	public void setOutputUpdatePolicy(MapperFunctionOutputUpdatePolicy policy) {
		//Do nothing
	}
}
